#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Streamlit凯利公式计算器
功能说明：基于Streamlit的交互式凯利公式计算器
作者：luohe
创建时间：2024-12-19
修改时间：2024-12-19
"""

import streamlit as st
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import plotly.graph_objects as go
import plotly.express as px
from plotly.subplots import make_subplots
import math
from typing import Tuple, Dict, List
from dataclasses import dataclass

# 配置页面
st.set_page_config(
    page_title="凯利公式计算器",
    page_icon="📊",
    layout="wide",
    initial_sidebar_state="expanded"
)

# 解决中文显示问题 - 使用plotly替代matplotlib
@dataclass
class KellyResult:
    """凯利公式计算结果数据类"""
    optimal_fraction: float  # 最优投资比例
    expected_growth: float   # 期望增长率
    risk_level: str         # 风险等级
    recommendation: str     # 投资建议
    conservative_fraction: float  # 保守投资比例
    aggressive_fraction: float   # 激进投资比例

class StreamlitKellyCalculator:
    """Streamlit凯利公式计算器"""
    
    def __init__(self):
        """初始化计算器"""
        if 'calculation_history' not in st.session_state:
            st.session_state.calculation_history = []
    
    def export_results_to_excel(self, kelly_result: KellyResult, win_rate: float, 
                               win_return: float, loss_rate: float) -> bytes:
        """导出计算结果到Excel文件
        
        Args:
            kelly_result: 凯利计算结果
            win_rate: 胜率
            win_return: 胜利收益率
            loss_rate: 失败损失率
            
        Returns:
            bytes: Excel文件的二进制数据
        """
        try:
            from io import BytesIO
            import xlsxwriter
            
            # 创建Excel文件
            output = BytesIO()
            workbook = xlsxwriter.Workbook(output, {'in_memory': True})
            
            # 创建工作表
            summary_sheet = workbook.add_worksheet('计算结果摘要')
            detail_sheet = workbook.add_worksheet('详细分析')
            
            # 设置格式
            header_format = workbook.add_format({
                'bold': True,
                'font_size': 12,
                'bg_color': '#4CAF50',
                'font_color': 'white'
            })
            
            data_format = workbook.add_format({
                'font_size': 11,
                'align': 'left'
            })
            
            percent_format = workbook.add_format({
                'num_format': '0.00%',
                'font_size': 11
            })
            
            # 写入摘要数据
            summary_data = [
                ['参数', '数值'],
                ['胜率', win_rate],
                ['胜利收益率', win_return],
                ['失败损失率', loss_rate],
                ['盈亏比', win_return / loss_rate],
                ['', ''],
                ['计算结果', ''],
                ['理论最优投资比例', kelly_result.optimal_fraction],
                ['期望增长率', kelly_result.expected_growth],
                ['风险等级', kelly_result.risk_level],
                ['保守策略比例', kelly_result.conservative_fraction],
                ['激进策略比例', kelly_result.aggressive_fraction],
                ['', ''],
                ['投资建议', kelly_result.recommendation]
            ]
            
            for row, (label, value) in enumerate(summary_data):
                if row == 0 or row == 6:  # 标题行
                    summary_sheet.write(row, 0, label, header_format)
                    summary_sheet.write(row, 1, value, header_format)
                elif isinstance(value, (int, float)) and row not in [4, 13]:  # 百分比数据
                    summary_sheet.write(row, 0, label, data_format)
                    summary_sheet.write(row, 1, value, percent_format)
                else:  # 文本数据
                    summary_sheet.write(row, 0, label, data_format)
                    summary_sheet.write(row, 1, value, data_format)
            
            # 调整列宽
            summary_sheet.set_column('A:A', 20)
            summary_sheet.set_column('B:B', 25)
            
            # 写入详细分析
            detail_sheet.write(0, 0, '凯利公式详细分析', header_format)
            detail_sheet.write(2, 0, '公式说明:', data_format)
            detail_sheet.write(3, 0, 'f* = (bp - q) / b', data_format)
            detail_sheet.write(4, 0, '其中:', data_format)
            detail_sheet.write(5, 0, 'f* = 最优投资比例', data_format)
            detail_sheet.write(6, 0, 'b = 盈亏比', data_format)
            detail_sheet.write(7, 0, 'p = 胜率', data_format)
            detail_sheet.write(8, 0, 'q = 败率 (1-p)', data_format)
            
            detail_sheet.set_column('A:A', 30)
            
            workbook.close()
            output.seek(0)
            
            return output.getvalue()
            
        except Exception as e:
            st.error(f"导出Excel文件时发生错误: {str(e)}")
            return b''
    
    def validate_inputs(self, win_rate: float, win_return: float, loss_rate: float) -> Tuple[bool, str]:
        """验证输入参数的有效性
        
        Args:
            win_rate: 胜利概率 (0-1)
            win_return: 胜利时收益率 (0-∞)
            loss_rate: 失败时损失率 (0-1)
            
        Returns:
            Tuple[bool, str]: (是否有效, 错误信息)
        """
        if not (0 < win_rate < 1):
            return False, f"胜率必须在0-100%之间，当前值：{win_rate:.1%}"
        
        if win_return <= 0:
            return False, f"胜利收益率必须大于0，当前值：{win_return:.1%}"
            
        if not (0 < loss_rate <= 1):
            return False, f"失败损失率必须在0-100%之间，当前值：{loss_rate:.1%}"
            
        return True, ""
    
    def calculate_kelly_fraction(self, win_rate: float, win_return: float, loss_rate: float) -> KellyResult:
        """计算凯利公式最优投资比例
        
        Args:
            win_rate: 胜利概率 (0-1)
            win_return: 胜利时收益率 (0-∞)
            loss_rate: 失败时损失率 (0-1)
            
        Returns:
            KellyResult: 包含计算结果的数据类
            
        Raises:
            ValueError: 当输入参数无效时
            ZeroDivisionError: 当损失率为0时
        """
        try:
            # 输入验证
            if loss_rate <= 0:
                raise ZeroDivisionError("失败损失率不能为0")
            
            # 凯利公式：f* = (bp - q) / b
            lose_rate = 1 - win_rate
            profit_loss_ratio = win_return / loss_rate
            
            # 计算最优投资比例
            optimal_fraction = (profit_loss_ratio * win_rate - lose_rate) / profit_loss_ratio
            optimal_fraction = max(0, min(optimal_fraction, 1.0))  # 限制在0-1之间
            
            # 计算期望增长率
            if optimal_fraction > 0 and optimal_fraction < 1:
                try:
                    expected_growth = (win_rate * math.log(1 + optimal_fraction * profit_loss_ratio) + 
                                     lose_rate * math.log(1 - optimal_fraction))
                except (ValueError, OverflowError):
                    expected_growth = 0  # 数值计算错误时设为0
            else:
                expected_growth = 0
            
            # 风险等级评估
            risk_level = self._assess_risk_level(optimal_fraction)
            
            # 生成投资建议
            recommendation = self._generate_recommendation(optimal_fraction)
            
            # 计算保守和激进投资比例
            conservative_fraction = optimal_fraction * 0.5  # 50%凯利
            aggressive_fraction = optimal_fraction * 0.75   # 75%凯利
            
            return KellyResult(
                optimal_fraction=optimal_fraction,
                expected_growth=expected_growth,
                risk_level=risk_level,
                recommendation=recommendation,
                conservative_fraction=conservative_fraction,
                aggressive_fraction=aggressive_fraction
            )
            
        except Exception as e:
            # 异常处理，返回安全的默认值
            st.error(f"计算过程中发生错误: {str(e)}")
            return KellyResult(
                optimal_fraction=0.0,
                expected_growth=0.0,
                risk_level="计算错误",
                recommendation="请检查输入参数",
                conservative_fraction=0.0,
                aggressive_fraction=0.0
            )
    
    def _assess_risk_level(self, fraction: float) -> str:
        """评估风险等级"""
        if fraction <= 0:
            return "无投资价值"
        elif fraction <= 0.1:
            return "低风险"
        elif fraction <= 0.25:
            return "中等风险"
        elif fraction <= 0.5:
            return "高风险"
        else:
            return "极高风险"
    
    def _generate_recommendation(self, fraction: float) -> str:
        """生成投资建议"""
        if fraction <= 0:
            return "不建议投资，期望收益为负"
        elif fraction <= 0.05:
            return "可以小额投资，建议谨慎操作"
        elif fraction <= 0.15:
            return "适度投资，建议使用50%-75%的凯利比例"
        elif fraction <= 0.3:
            return "高收益潜力，但风险较大，建议使用25%-50%的凯利比例"
        else:
            return "理论收益很高但风险极大，强烈建议降低投资比例至25%以下"
    
    def calculate_growth_curve(self, win_rate: float, win_return: float, loss_rate: float, 
                             max_fraction: float = 1.0, points: int = 100) -> pd.DataFrame:
        """计算不同投资比例下的增长率曲线"""
        fractions = np.linspace(0, max_fraction, points)
        growth_rates = []
        
        lose_rate = 1 - win_rate
        profit_loss_ratio = win_return / loss_rate
        
        for f in fractions:
            if f == 0:
                growth = 0
            elif f >= 1 / profit_loss_ratio:  # 避免破产
                growth = -10  # 设置一个较大的负值而不是-inf
            else:
                try:
                    growth = (win_rate * math.log(1 + f * profit_loss_ratio) + 
                             lose_rate * math.log(1 - f))
                except (ValueError, OverflowError):
                    growth = -10
            
            growth_rates.append(growth)
        
        return pd.DataFrame({
            '投资比例': fractions,
            '期望增长率': growth_rates
        })
    
    def plot_growth_curve(self, win_rate: float, win_return: float, loss_rate: float, kelly_result: KellyResult):
        """绘制增长率曲线"""
        curve_data = self.calculate_growth_curve(win_rate, win_return, loss_rate)
        
        # 过滤极值
        valid_data = curve_data[curve_data['期望增长率'] > -5]
        
        fig = go.Figure()
        
        # 增长率曲线
        fig.add_trace(go.Scatter(
            x=valid_data['投资比例'],
            y=valid_data['期望增长率'],
            mode='lines',
            name='期望增长率',
            line=dict(color='blue', width=3)
        ))
        
        # 最优比例线
        fig.add_vline(
            x=kelly_result.optimal_fraction,
            line_dash="dash",
            line_color="red",
            annotation_text=f"最优比例: {kelly_result.optimal_fraction:.1%}"
        )
        
        # 保守比例线
        fig.add_vline(
            x=kelly_result.conservative_fraction,
            line_dash="dot",
            line_color="green",
            annotation_text=f"保守比例: {kelly_result.conservative_fraction:.1%}"
        )
        
        # 激进比例线
        fig.add_vline(
            x=kelly_result.aggressive_fraction,
            line_dash="dot",
            line_color="orange",
            annotation_text=f"激进比例: {kelly_result.aggressive_fraction:.1%}"
        )
        
        fig.update_layout(
            title="凯利增长率曲线",
            xaxis_title="投资比例",
            yaxis_title="期望增长率",
            hovermode='x unified'
        )
        
        return fig
    
    def plot_risk_return_analysis(self, win_rate: float, win_return: float, loss_rate: float, kelly_result: KellyResult):
        """绘制风险收益分析图"""
        fractions = [0.05, 0.1, 0.15, 0.2, 0.25, 0.3, 0.4, 0.5, 
                    kelly_result.conservative_fraction, kelly_result.aggressive_fraction, 
                    kelly_result.optimal_fraction]
        
        returns = []
        risks = []
        labels = []
        
        for i, f in enumerate(fractions):
            if f > 0:
                # 模拟收益和风险
                sim_returns = []
                for _ in range(1000):
                    if np.random.random() < win_rate:
                        sim_returns.append(f * win_return)
                    else:
                        sim_returns.append(-f * loss_rate)
                
                returns.append(np.mean(sim_returns))
                risks.append(np.std(sim_returns))
                
                if i == len(fractions) - 3:
                    labels.append(f"保守策略 ({f:.1%})")
                elif i == len(fractions) - 2:
                    labels.append(f"激进策略 ({f:.1%})")
                elif i == len(fractions) - 1:
                    labels.append(f"凯利最优 ({f:.1%})")
                else:
                    labels.append(f"{f:.1%}")
            else:
                returns.append(0)
                risks.append(0)
                labels.append("0%")
        
        fig = go.Figure()
        
        # 普通点
        fig.add_trace(go.Scatter(
            x=risks[:-3],
            y=returns[:-3],
            mode='markers',
            name='常规比例',
            marker=dict(size=10, color='lightblue'),
            text=labels[:-3],
            hovertemplate='投资比例: %{text}<br>风险: %{x:.4f}<br>收益: %{y:.4f}<extra></extra>'
        ))
        
        # 特殊策略点
        colors = ['green', 'orange', 'red']
        names = ['保守策略', '激进策略', '凯利最优']
        
        for i, (color, name) in enumerate(zip(colors, names)):
            fig.add_trace(go.Scatter(
                x=[risks[-3+i]],
                y=[returns[-3+i]],
                mode='markers',
                name=name,
                marker=dict(size=15, color=color, symbol='star'),
                text=[labels[-3+i]],
                hovertemplate=f'{name}<br>风险: %{{x:.4f}}<br>收益: %{{y:.4f}}<extra></extra>'
            ))
        
        fig.update_layout(
            title="风险-收益分析",
            xaxis_title="风险 (标准差)",
            yaxis_title="期望收益",
            hovermode='closest'
        )
        
        return fig
    
    def create_strategy_comparison(self, kelly_result: KellyResult):
        """创建策略对比雷达图"""
        categories = ['收益潜力', '风险控制', '实用性', '稳定性', '推荐度']
        
        # 策略评分
        optimal_scores = [5, 2, 3, 3, 3]  # 理论最优
        conservative_scores = [3, 5, 5, 5, 5]  # 保守策略
        aggressive_scores = [4, 3, 4, 3, 4]  # 激进策略
        
        fig = go.Figure()
        
        fig.add_trace(go.Scatterpolar(
            r=optimal_scores,
            theta=categories,
            fill='toself',
            name='理论最优',
            line_color='red'
        ))
        
        fig.add_trace(go.Scatterpolar(
            r=conservative_scores,
            theta=categories,
            fill='toself',
            name='保守策略',
            line_color='green'
        ))
        
        fig.add_trace(go.Scatterpolar(
            r=aggressive_scores,
            theta=categories,
            fill='toself',
            name='激进策略',
            line_color='orange'
        ))
        
        fig.update_layout(
            polar=dict(
                radialaxis=dict(
                    visible=True,
                    range=[0, 5]
                )
            ),
            title="策略对比分析",
            showlegend=True
        )
        
        return fig
    
    def run_simulation(self, win_rate: float, win_return: float, loss_rate: float, 
                      fraction: float, initial_capital: float = 10000, trades: int = 100) -> List[float]:
        """运行投资模拟
        
        Args:
            win_rate: 胜利概率 (0-1)
            win_return: 胜利时收益率 (0-∞)
            loss_rate: 失败时损失率 (0-1)
            fraction: 投资比例 (0-1)
            initial_capital: 初始资金
            trades: 交易次数
            
        Returns:
            List[float]: 资金历史记录
            
        Raises:
            ValueError: 当参数无效时
        """
        try:
            # 参数验证
            if initial_capital <= 0:
                raise ValueError("初始资金必须大于0")
            if trades <= 0:
                raise ValueError("交易次数必须大于0")
            if not (0 <= fraction <= 1):
                raise ValueError("投资比例必须在0-1之间")
            
            capital_history = [initial_capital]
            current_capital = initial_capital
            
            # 使用numpy进行向量化计算以提高性能
            random_outcomes = np.random.random(trades)
            
            for i in range(trades):
                # 防止资金为负
                if current_capital <= 0:
                    capital_history.extend([0] * (trades - i))
                    break
                
                bet_amount = current_capital * fraction
                
                if random_outcomes[i] < win_rate:
                    # 胜利
                    current_capital += bet_amount * win_return
                else:
                    # 失败
                    current_capital = max(0, current_capital - bet_amount * loss_rate)
                
                capital_history.append(current_capital)
            
            return capital_history
            
        except Exception as e:
            st.error(f"模拟过程中发生错误: {str(e)}")
            return [initial_capital] * (trades + 1)  # 返回平稳的资金线

def main():
    """主函数"""
    st.title("📊 凯利公式计算器")
    st.markdown("---")
    
    calculator = StreamlitKellyCalculator()
    
    # 侧边栏输入
    with st.sidebar:
        st.header("📝 参数设置")
        
        # 输入参数
        st.subheader("📊 核心参数")
        
        win_rate_percent = st.number_input(
            "胜率 (%)", 
            min_value=0.1, 
            max_value=99.9, 
            value=60.0, 
            step=0.1,
            format="%.1f",
            help="交易获胜的概率百分比"
        )
        win_rate = win_rate_percent / 100
        
        win_return_percent = st.number_input(
            "胜利收益率 (%)", 
            min_value=0.1, 
            max_value=1000.0, 
            value=20.0, 
            step=0.1,
            format="%.1f",
            help="交易获胜时的收益率百分比"
        )
        win_return = win_return_percent / 100
        
        loss_rate_percent = st.number_input(
            "失败损失率 (%)", 
            min_value=0.1, 
            max_value=100.0, 
            value=10.0, 
            step=0.1,
            format="%.1f",
            help="交易失败时的损失率百分比"
        )
        loss_rate = loss_rate_percent / 100
        
        # 显示计算的盈亏比
        st.info(f"💡 当前盈亏比：{win_return/loss_rate:.2f}:1")
        
        st.markdown("---")
        
        # 模拟参数
        st.subheader("🎲 模拟设置")
        initial_capital = st.number_input("初始资金", 1000, 1000000, 10000, 1000)
        simulation_trades = st.number_input(
            "模拟交易次数", 
            min_value=10, 
            max_value=10000, 
            value=100, 
            step=10,
            help="设置模拟交易的次数，用于测试不同策略的表现"
        )
        
        # 计算按钮
        calculate_button = st.button("🚀 开始计算", type="primary")
    
    # 主要内容区域
    if calculate_button:
        # 验证输入
        is_valid, error_msg = calculator.validate_inputs(win_rate, win_return, loss_rate)
        
        if not is_valid:
            st.error(f"❌ 输入错误：{error_msg}")
            return
        
        # 计算凯利结果
        kelly_result = calculator.calculate_kelly_fraction(win_rate, win_return, loss_rate)
        
        # 保存到历史记录
        st.session_state.calculation_history.append({
            '时间': pd.Timestamp.now().strftime('%Y-%m-%d %H:%M:%S'),
            '胜率': f"{win_rate:.1%}",
            '胜利收益率': f"{win_return:.1%}",
            '失败损失率': f"{loss_rate:.1%}",
            '最优比例': f"{kelly_result.optimal_fraction:.2%}",
            '风险等级': kelly_result.risk_level
        })
        
        # 显示核心结果
        st.header("🎯 计算结果")
        
        col1, col2, col3, col4 = st.columns(4)
        
        with col1:
            st.metric(
                "理论最优投资比例",
                f"{kelly_result.optimal_fraction:.2%}",
                help="根据凯利公式计算的理论最优投资比例"
            )
        
        with col2:
            st.metric(
                "期望增长率",
                f"{kelly_result.expected_growth:.2%}",
                help="使用最优比例时的期望增长率"
            )
        
        with col3:
            st.metric(
                "风险等级",
                kelly_result.risk_level,
                help="基于投资比例评估的风险等级"
            )
        
        with col4:
            st.metric(
                "盈亏比",
                f"{win_return/loss_rate:.2f}:1",
                help="胜利收益率与失败损失率的比值"
            )
        
        # 投资建议
        st.subheader("💡 投资建议")
        
        col1, col2 = st.columns(2)
        
        with col1:
            st.info(f"**保守策略：** {kelly_result.conservative_fraction:.2%} (50%凯利)")
            st.success(f"**激进策略：** {kelly_result.aggressive_fraction:.2%} (75%凯利)")
        
        with col2:
            st.warning(f"**专业建议：** {kelly_result.recommendation}")
        
        # 导出功能
        st.subheader("📥 导出报告")
        col1, col2 = st.columns(2)
        
        with col1:
            if st.button("📊 导出Excel报告", type="secondary"):
                try:
                    excel_data = calculator.export_results_to_excel(kelly_result, win_rate, win_return, loss_rate)
                    if excel_data:
                        st.download_button(
                            label="⬇️ 下载Excel文件",
                            data=excel_data,
                            file_name=f"凯利公式计算报告_{pd.Timestamp.now().strftime('%Y%m%d_%H%M%S')}.xlsx",
                            mime="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
                        )
                        st.success("✅ Excel报告已准备就绪，点击下载按钮保存文件")
                except Exception as e:
                    st.error(f"生成Excel报告失败: {str(e)}")
        
        with col2:
            # 添加快速复制功能
            summary_text = f"""凯利公式计算结果摘要
胜率: {win_rate:.1%}
胜利收益率: {win_return:.1%}
失败损失率: {loss_rate:.1%}
盈亏比: {win_return/loss_rate:.2f}:1
理论最优投资比例: {kelly_result.optimal_fraction:.2%}
期望增长率: {kelly_result.expected_growth:.2%}
风险等级: {kelly_result.risk_level}
保守策略: {kelly_result.conservative_fraction:.2%}
激进策略: {kelly_result.aggressive_fraction:.2%}
投资建议: {kelly_result.recommendation}"""
            
            if st.button("📋 复制结果摘要"):
                st.code(summary_text, language="text")
                st.info("💡 请手动复制上方文本框中的内容")
        
        # 可视化分析
        st.header("📈 可视化分析")
        
        tab1, tab2, tab3, tab4 = st.tabs(["增长率曲线", "风险收益分析", "策略对比", "模拟测试"])
        
        with tab1:
            st.plotly_chart(calculator.plot_growth_curve(win_rate, win_return, loss_rate, kelly_result), use_container_width=True)
        
        with tab2:
            st.plotly_chart(calculator.plot_risk_return_analysis(win_rate, win_return, loss_rate, kelly_result), use_container_width=True)
        
        with tab3:
            st.plotly_chart(calculator.create_strategy_comparison(kelly_result), use_container_width=True)
        
        with tab4:
            st.subheader("🎲 投资策略模拟")
            
            # 模拟不同策略
            strategies = {
                '保守策略': kelly_result.conservative_fraction,
                '激进策略': kelly_result.aggressive_fraction,
                '理论最优': kelly_result.optimal_fraction
            }
            
            simulation_results = {}
            
            for name, fraction in strategies.items():
                if fraction > 0:
                    capital_history = calculator.run_simulation(
                        win_rate, win_return, loss_rate, fraction, initial_capital, simulation_trades
                    )
                    simulation_results[name] = capital_history
            
            # 绘制模拟结果
            if simulation_results:
                fig = go.Figure()
                
                colors = ['green', 'orange', 'red']
                for i, (name, history) in enumerate(simulation_results.items()):
                    fig.add_trace(go.Scatter(
                        x=list(range(len(history))),
                        y=history,
                        mode='lines',
                        name=name,
                        line=dict(color=colors[i % len(colors)], width=2)
                    ))
                
                fig.update_layout(
                    title=f"资金曲线模拟 ({simulation_trades}次交易)",
                    xaxis_title="交易次数",
                    yaxis_title="资金金额",
                    hovermode='x unified'
                )
                
                st.plotly_chart(fig, use_container_width=True)
                
                # 模拟结果统计
                st.subheader("📊 模拟结果统计")
                
                results_df = pd.DataFrame({
                    '策略': list(simulation_results.keys()),
                    '最终资金': [history[-1] for history in simulation_results.values()],
                    '总收益率': [(history[-1] / initial_capital - 1) * 100 for history in simulation_results.values()],
                    '最大资金': [max(history) for history in simulation_results.values()],
                    '最小资金': [min(history) for history in simulation_results.values()]
                })
                
                results_df['最终资金'] = results_df['最终资金'].apply(lambda x: f"{x:,.0f}")
                results_df['总收益率'] = results_df['总收益率'].apply(lambda x: f"{x:.1f}%")
                results_df['最大资金'] = results_df['最大资金'].apply(lambda x: f"{x:,.0f}")
                results_df['最小资金'] = results_df['最小资金'].apply(lambda x: f"{x:,.0f}")
                
                st.dataframe(results_df, use_container_width=True)
    
    # 历史记录
    if st.session_state.calculation_history:
        st.header("📋 计算历史")
        history_df = pd.DataFrame(st.session_state.calculation_history)
        st.dataframe(history_df, use_container_width=True)
        
        if st.button("🗑️ 清空历史记录"):
            st.session_state.calculation_history = []
            st.rerun()
    
    # 帮助信息
    with st.expander("❓ 使用说明"):
        st.markdown("""
        ### 凯利公式说明
        
        凯利公式是一个用于确定最优投资比例的数学公式：
        
        **f* = (bp - q) / b**
        
        其中：
        - f* = 最优投资比例
        - b = 盈亏比 (胜利收益率 / 失败损失率)
        - p = 胜率
        - q = 败率 (1 - 胜率)
        
        ### 使用建议
        
        1. **保守策略**：使用理论最优值的50%
        2. **激进策略**：使用理论最优值的75%
        3. **风险控制**：避免使用100%的理论最优值
        4. **动态调整**：根据市场变化及时调整参数
        
        ### 注意事项
        
        - 凯利公式基于理论假设，实际应用需要考虑更多因素
        - 高投资比例虽然理论收益高，但破产风险也相应增加
        - 建议结合实际情况和风险承受能力进行调整
        """)

if __name__ == "__main__":
    main()